home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / answers / Objective-C / sample < prev    next >
Encoding:
Text File  |  1993-06-16  |  24.1 KB  |  984 lines

  1. Path: senator-bedfellow.mit.edu!enterpoop.mit.edu!usc!cs.utexas.edu!uunet!mcsun!sun4nl!tuegate.tue.nl!viper.es.ele.tue.nl!viper.es.ele.tue.nl!tiggr
  2. From: tiggr@es.ele.tue.nl (Tiggr)
  3. Newsgroups: comp.lang.objective-c,comp.answers,news.answers
  4. Subject: comp.lang.objective-c FAQ, part 3/3: A Sample Program
  5. Supersedes: <sample_740305123@es.ele.tue.nl>
  6. Followup-To: comp.lang.objective-c
  7. Date: 17 Jun 1993 08:23:34 GMT
  8. Organization: Eindhoven University of Technology
  9. Lines: 963
  10. Approved: news-answers-request@mit.edu
  11. Message-ID: <sample_740305413@es.ele.tue.nl>
  12. Reply-To: tiggr@es.ele.tue.nl (Tiggr)
  13. NNTP-Posting-Host: viper.es.ele.tue.nl
  14. Summary: This third part of the comp.lang.objective-c FAQ postings
  15.         presents a simple sample program written in Objective-C.
  16.         It can be compiled using the publicly available GNU CC
  17.         compiler, version 2.3.3 or later.
  18. Originator: tiggr@viper.es.ele.tue.nl
  19. Xref: senator-bedfellow.mit.edu comp.lang.objective-c:1313 comp.answers:1032 news.answers:9505
  20.  
  21. Archive-name: Objective-C/sample
  22. Version: $Id: sample.preamble,v 1.4 1993/06/17 08:08:56 tiggr Exp $
  23.  
  24.  
  25.         A simple sample
  26.         Objective-C program
  27.  
  28.  
  29. This is the third part in a series of three informational postings
  30. concerning comp.lang.objective-c.  This article presents a simple program
  31. written in Objective-C.  The program consist of several files which are
  32. contained in a shar file (see instructions below on how to unpack).
  33.  
  34. The early version of this FAQ was compiled by Bill Shirley, with the aid of
  35. many people.  The current version is being maintained by Tiggr, aided by a
  36. lot of people, including Paul Burchard and Bill Shirly.
  37.  
  38. Any text in between `[' and `]' is a comment.  Comments indicate problems
  39. with this FAQ, which should be solved.  Send your suggestions, additions,
  40. bug reports, comments and fixes to `tiggr@es.ele.tue.nl'.
  41.  
  42.  
  43. #---------------------------------- cut here ----------------------------------
  44. # This is a shell archive.  Remove anything before this line,
  45. # then unpack it by saving it in a file and typing "sh file".
  46. #
  47. # Wrapped by Pieter Schoenmakers <tiggr@viper> on Thu Jun 17 10:23:18 1993
  48. #
  49. # This archive contains:
  50. #    objc-sample    
  51. #
  52. # Existing files will not be overwritten.
  53. # Error checking via wc(1) will be performed.
  54.  
  55. LANG=""; export LANG
  56. PATH=/bin:/usr/bin:$PATH; export PATH
  57.  
  58. echo mkdir - objc-sample
  59. mkdir objc-sample
  60.  
  61. if test -f objc-sample/README
  62. then
  63.     echo Ok to overwrite existing file objc-sample/README\?
  64.     read answer
  65.     case "$answer" in
  66.     [yY]*)    echo Proceeding;;
  67.     *)    echo Aborting; exit 1;;
  68.     esac
  69.     rm -f objc-sample/README
  70.     if test -f objc-sample/README
  71.     then
  72.         echo Error: could not remove objc-sample/README, aborting
  73.         exit 1
  74.     fi
  75. fi
  76. echo x - objc-sample/README
  77. cat >objc-sample/README <<'@EOF'
  78. This directory contains the complete code for the "S[ia]mple Objective-C
  79. program" described in comp.lang.objective-c FAQ.  If you have a suitable
  80. compiler, use the supplied Makefile.  Otherwise, program output can be
  81. found in the file "output".
  82.  
  83. You should probably read "main.m" first.  It is very heavily annotated.
  84.  
  85. Also note and read the file COPYRIGHT.
  86. @EOF
  87. set `wc -lwc <objc-sample/README`
  88. if test $1$2$3 != 853358
  89. then
  90.     echo ERROR: wc results of objc-sample/README are $* should be 8 53 358
  91. fi
  92.  
  93. chmod 644 objc-sample/README
  94.  
  95. if test -f objc-sample/Char.h
  96. then
  97.     echo Ok to overwrite existing file objc-sample/Char.h\?
  98.     read answer
  99.     case "$answer" in
  100.     [yY]*)    echo Proceeding;;
  101.     *)    echo Aborting; exit 1;;
  102.     esac
  103.     rm -f objc-sample/Char.h
  104.     if test -f objc-sample/Char.h
  105.     then
  106.         echo Error: could not remove objc-sample/Char.h, aborting
  107.         exit 1
  108.     fi
  109. fi
  110. echo x - objc-sample/Char.h
  111. cat >objc-sample/Char.h <<'@EOF'
  112. #import <objc/Object.h>
  113.  
  114. @interface Char: Object
  115. {
  116.   int value;
  117. }
  118.  
  119. - init: (int) x;
  120. - report;
  121.  
  122. @end
  123. @EOF
  124. set `wc -lwc <objc-sample/Char.h`
  125. if test $1$2$3 != 1116100
  126. then
  127.     echo ERROR: wc results of objc-sample/Char.h are $* should be 11 16 100
  128. fi
  129.  
  130. chmod 644 objc-sample/Char.h
  131.  
  132. if test -f objc-sample/Node.h
  133. then
  134.     echo Ok to overwrite existing file objc-sample/Node.h\?
  135.     read answer
  136.     case "$answer" in
  137.     [yY]*)    echo Proceeding;;
  138.     *)    echo Aborting; exit 1;;
  139.     esac
  140.     rm -f objc-sample/Node.h
  141.     if test -f objc-sample/Node.h
  142.     then
  143.         echo Error: could not remove objc-sample/Node.h, aborting
  144.         exit 1
  145.     fi
  146. fi
  147. echo x - objc-sample/Node.h
  148. cat >objc-sample/Node.h <<'@EOF'
  149.  
  150. // Node.h - comp.lang.objective-c simple sample Objective-C program
  151.  
  152. #import <objc/Object.h>
  153.  
  154. @interface      Node : Object
  155. {
  156.   id    next;
  157.   id    data;
  158. }
  159.  
  160.  +    new: anItem;     // create a Node and store anItem in it
  161.  -     free;         // free a Node and return the item in it
  162.  -     next;         // report the id of the next node after this one
  163.  -    set_next: aNode; // make the next node be aNode
  164. @end
  165. @EOF
  166. set `wc -lwc <objc-sample/Node.h`
  167. if test $1$2$3 != 1668379
  168. then
  169.     echo ERROR: wc results of objc-sample/Node.h are $* should be 16 68 379
  170. fi
  171.  
  172. chmod 644 objc-sample/Node.h
  173.  
  174. if test -f objc-sample/Node.m
  175. then
  176.     echo Ok to overwrite existing file objc-sample/Node.m\?
  177.     read answer
  178.     case "$answer" in
  179.     [yY]*)    echo Proceeding;;
  180.     *)    echo Aborting; exit 1;;
  181.     esac
  182.     rm -f objc-sample/Node.m
  183.     if test -f objc-sample/Node.m
  184.     then
  185.         echo Error: could not remove objc-sample/Node.m, aborting
  186.         exit 1
  187.     fi
  188. fi
  189. echo x - objc-sample/Node.m
  190. cat >objc-sample/Node.m <<'@EOF'
  191.  
  192. // Node.m - comp.lang.objective-c simple sample Objective-C program
  193.  
  194. #import <objc/Object.h>
  195. #import "Node.h"
  196.  
  197. @implementation    Node : Object
  198.  
  199. + new: anItem
  200. {
  201.     self = [super new];
  202.     next = 0;
  203.     data = anItem;
  204.     return self;
  205. }
  206.  
  207. - free
  208. {
  209.     id tmp = data;
  210.     [super free];
  211.     return tmp;
  212. }
  213.  
  214. - next { return next; }
  215.  
  216. - set_next: aNode { next = aNode; return self; }
  217.  
  218. @end
  219. @EOF
  220. set `wc -lwc <objc-sample/Node.m`
  221. if test $1$2$3 != 2862381
  222. then
  223.     echo ERROR: wc results of objc-sample/Node.m are $* should be 28 62 381
  224. fi
  225.  
  226. chmod 644 objc-sample/Node.m
  227.  
  228. if test -f objc-sample/Queue.h
  229. then
  230.     echo Ok to overwrite existing file objc-sample/Queue.h\?
  231.     read answer
  232.     case "$answer" in
  233.     [yY]*)    echo Proceeding;;
  234.     *)    echo Aborting; exit 1;;
  235.     esac
  236.     rm -f objc-sample/Queue.h
  237.     if test -f objc-sample/Queue.h
  238.     then
  239.         echo Error: could not remove objc-sample/Queue.h, aborting
  240.         exit 1
  241.     fi
  242. fi
  243. echo x - objc-sample/Queue.h
  244. cat >objc-sample/Queue.h <<'@EOF'
  245.  
  246. // Queue.h - comp.lang.objective-c simple sample Objective-C program
  247.  
  248. #import <objc/Object.h>
  249. #import "Node.h"
  250.  
  251. @interface    Queue : Object
  252. {
  253.     id    head;
  254.     id    tail;
  255.     unsigned    qsize;
  256. }
  257.  
  258.  +        new;        // create a new Queue
  259.  -        empty;        // clear out all contents of the Queue
  260.  -        put: anItem;    // put anItem on the Queue
  261.  -        get;        // return the item on top of the Queue
  262.  - (unsigned)    size;        // tell us the current size of the Queue
  263. @end
  264. @EOF
  265. set `wc -lwc <objc-sample/Queue.h`
  266. if test $1$2$3 != 1974433
  267. then
  268.     echo ERROR: wc results of objc-sample/Queue.h are $* should be 19 74 433
  269. fi
  270.  
  271. chmod 644 objc-sample/Queue.h
  272.  
  273. if test -f objc-sample/Queue.m
  274. then
  275.     echo Ok to overwrite existing file objc-sample/Queue.m\?
  276.     read answer
  277.     case "$answer" in
  278.     [yY]*)    echo Proceeding;;
  279.     *)    echo Aborting; exit 1;;
  280.     esac
  281.     rm -f objc-sample/Queue.m
  282.     if test -f objc-sample/Queue.m
  283.     then
  284.         echo Error: could not remove objc-sample/Queue.m, aborting
  285.         exit 1
  286.     fi
  287. fi
  288. echo x - objc-sample/Queue.m
  289. cat >objc-sample/Queue.m <<'@EOF'
  290.  
  291. // Queue.m - comp.lang.objective-c simple sample Objective-C program
  292.  
  293. #import "Queue.h"
  294.  
  295. @implementation    Queue
  296.  
  297. + new
  298. {
  299.     self = [super new];
  300.     head = tail = 0;
  301.     qsize = 0;
  302.     return self;
  303. }
  304.  
  305. - empty
  306. {
  307.     while([self size])
  308.     [[self get] free];
  309.     return self;
  310. }
  311.  
  312. - put: anItem
  313. {
  314.   if (tail)
  315.     tail = [[tail set_next : [Node new : anItem]] next];
  316.   else
  317.     head = tail = [Node new : anItem];
  318.   ++qsize;
  319.     return self;
  320. }
  321.  
  322. - get
  323. {
  324.   id contents;
  325.   id old_head = head;
  326.   head = [head next];
  327.   contents = [old_head free];
  328.   if (--qsize == 0)
  329.       tail = head;
  330.   return contents;
  331. }
  332.  
  333. - (unsigned) size { return qsize; }
  334.  
  335. @end
  336. @EOF
  337. set `wc -lwc <objc-sample/Queue.m`
  338. if test $1$2$3 != 46105630
  339. then
  340.     echo ERROR: wc results of objc-sample/Queue.m are $* should be 46 105 630
  341. fi
  342.  
  343. chmod 644 objc-sample/Queue.m
  344.  
  345. if test -f objc-sample/Stack.h
  346. then
  347.     echo Ok to overwrite existing file objc-sample/Stack.h\?
  348.     read answer
  349.     case "$answer" in
  350.     [yY]*)    echo Proceeding;;
  351.     *)    echo Aborting; exit 1;;
  352.     esac
  353.     rm -f objc-sample/Stack.h
  354.     if test -f objc-sample/Stack.h
  355.     then
  356.         echo Error: could not remove objc-sample/Stack.h, aborting
  357.         exit 1
  358.     fi
  359. fi
  360. echo x - objc-sample/Stack.h
  361. cat >objc-sample/Stack.h <<'@EOF'
  362.  
  363. // Stack.h - comp.lang.objective-c simple sample Objective-C program
  364.  
  365. #import <objc/Object.h>
  366. #import "Node.h"
  367.  
  368. @interface    Stack : Object
  369. {
  370.     id        stack;
  371.     unsigned    stack_size;
  372. }
  373.  
  374.  +        new;        // create a new Stack
  375.  -        empty;        // clear out all contents of the Stack
  376.  -        put: anItem;    // put anItem on the Stack
  377.  -        get;        // return the item on top of the Stack
  378.  - (unsigned)    size;        // tell us the current size of the Stack
  379. @end
  380. @EOF
  381. set `wc -lwc <objc-sample/Stack.h`
  382. if test $1$2$3 != 1872421
  383. then
  384.     echo ERROR: wc results of objc-sample/Stack.h are $* should be 18 72 421
  385. fi
  386.  
  387. chmod 644 objc-sample/Stack.h
  388.  
  389. if test -f objc-sample/Stack.m
  390. then
  391.     echo Ok to overwrite existing file objc-sample/Stack.m\?
  392.     read answer
  393.     case "$answer" in
  394.     [yY]*)    echo Proceeding;;
  395.     *)    echo Aborting; exit 1;;
  396.     esac
  397.     rm -f objc-sample/Stack.m
  398.     if test -f objc-sample/Stack.m
  399.     then
  400.         echo Error: could not remove objc-sample/Stack.m, aborting
  401.         exit 1
  402.     fi
  403. fi
  404. echo x - objc-sample/Stack.m
  405. cat >objc-sample/Stack.m <<'@EOF'
  406.  
  407. // Stack.m - comp.lang.objective-c simple sample Objective-C program
  408.  
  409. #import "Stack.h"
  410.  
  411. @implementation    Stack
  412.  
  413. + new
  414. {
  415.     self = [super new];
  416.     stack = 0;
  417.     stack_size = 0;
  418.     return self;
  419. }
  420.  
  421. - empty
  422. {
  423.     while([self size])
  424.     [[self get] free];
  425.     return self;
  426. }
  427.  
  428. - put: anItem
  429. {
  430.   stack = [[Node new : anItem] set_next : stack];
  431.   ++stack_size;
  432.   return self;
  433. }
  434.  
  435. - get
  436. {
  437.   id contents;
  438.   id old_stack = stack;
  439.   stack = [stack next];
  440.   contents = [old_stack free];
  441.   --stack_size;
  442.   return contents;
  443. }
  444.  
  445. - (unsigned) size { return stack_size; }
  446.  
  447. @end
  448. @EOF
  449. set `wc -lwc <objc-sample/Stack.m`
  450. if test $1$2$3 != 4285560
  451. then
  452.     echo ERROR: wc results of objc-sample/Stack.m are $* should be 42 85 560
  453. fi
  454.  
  455. chmod 644 objc-sample/Stack.m
  456.  
  457. if test -f objc-sample/output
  458. then
  459.     echo Ok to overwrite existing file objc-sample/output\?
  460.     read answer
  461.     case "$answer" in
  462.     [yY]*)    echo Proceeding;;
  463.     *)    echo Aborting; exit 1;;
  464.     esac
  465.     rm -f objc-sample/output
  466.     if test -f objc-sample/output
  467.     then
  468.         echo Error: could not remove objc-sample/output, aborting
  469.         exit 1
  470.     fi
  471. fi
  472. echo x - objc-sample/output
  473. cat >objc-sample/output <<'@EOF'
  474. Output from demo, excluding Char class:
  475.  
  476. Include the Char class in the demo? (y/n): n
  477. queue:   5, stack:-5.0
  478. queue: 4.0, stack:  -4
  479. queue:   3, stack:-3.0
  480. queue: 2.0, stack:  -2
  481. queue:   1, stack:-1.0
  482. queue: 0.0, stack:   0
  483. queue:  -1, stack: 1.0
  484. queue:-2.0, stack:   2
  485. queue:  -3, stack: 3.0
  486. queue:-4.0, stack:   4
  487. queue:  -5, stack: 5.0
  488.  
  489. Output from demo, including Char class:
  490.  
  491. Include the Char class in the demo? (y/n): y
  492. queue:   5, stack:   h
  493. queue:   q, stack:-4.0
  494. queue:   3, stack:   j
  495. queue:   o, stack:-2.0
  496. queue:   1, stack:   l
  497. queue:   m, stack: 0.0
  498. queue:  -1, stack:   n
  499. queue:   k, stack: 2.0
  500. queue:  -3, stack:   p
  501. queue:   i, stack: 4.0
  502. queue:  -5, stack:   r
  503. @EOF
  504. set `wc -lwc <objc-sample/output`
  505. if test $1$2$3 != 29111679
  506. then
  507.     echo ERROR: wc results of objc-sample/output are $* should be 29 111 679
  508. fi
  509.  
  510. chmod 644 objc-sample/output
  511.  
  512. if test -f objc-sample/Char.m
  513. then
  514.     echo Ok to overwrite existing file objc-sample/Char.m\?
  515.     read answer
  516.     case "$answer" in
  517.     [yY]*)    echo Proceeding;;
  518.     *)    echo Aborting; exit 1;;
  519.     esac
  520.     rm -f objc-sample/Char.m
  521.     if test -f objc-sample/Char.m
  522.     then
  523.         echo Error: could not remove objc-sample/Char.m, aborting
  524.         exit 1
  525.     fi
  526. fi
  527. echo x - objc-sample/Char.m
  528. cat >objc-sample/Char.m <<'@EOF'
  529. #import <stdio.h>
  530. #import "Char.h"
  531.  
  532. @implementation Char
  533. {
  534.   int value;
  535. }
  536.  
  537. - init: (int) x
  538. {
  539.   [super init];        // In case the parent class is doing
  540.               // something special in its init...
  541.   value = x;
  542.   return self;
  543. }
  544.  
  545. - report
  546. {
  547.   printf("   %c", value);
  548.   return self;
  549. }
  550.  
  551. @end
  552. @EOF
  553. set `wc -lwc <objc-sample/Char.m`
  554. if test $1$2$3 != 2347279
  555. then
  556.     echo ERROR: wc results of objc-sample/Char.m are $* should be 23 47 279
  557. fi
  558.  
  559. chmod 644 objc-sample/Char.m
  560.  
  561. if test -f objc-sample/Makefile
  562. then
  563.     echo Ok to overwrite existing file objc-sample/Makefile\?
  564.     read answer
  565.     case "$answer" in
  566.     [yY]*)    echo Proceeding;;
  567.     *)    echo Aborting; exit 1;;
  568.     esac
  569.     rm -f objc-sample/Makefile
  570.     if test -f objc-sample/Makefile
  571.     then
  572.         echo Error: could not remove objc-sample/Makefile, aborting
  573.         exit 1
  574.     fi
  575. fi
  576. echo x - objc-sample/Makefile
  577. cat >objc-sample/Makefile <<'@EOF'
  578. # This Makefile assumes you have GNU gcc 2.3 or better and a suitable
  579. # runtime library with object support.  It also works on a NeXT.  Don't know
  580. # about Stepstone.
  581.  
  582. .SUFFIXES: .o .m
  583. .m.o:
  584.     $(CC) -c $(CFLAGS) $<
  585.  
  586. # Use this on a NeXT
  587. #CC=        cc
  588. #LIBS=        
  589. # Use this with GNU CC on a non-NeXT.
  590. CC=        gcc
  591. LIBS=        -lobjc
  592.  
  593. CFLAGS=        -Wall -O2 -g
  594. OFILES=        main.o Node.o Queue.o Stack.o Float.o Char.o
  595.  
  596. demo: $(OFILES)
  597.     $(CC) $(CFLAGS) $(LDFLAGS) -o demo $(OFILES) $(LIBS)
  598.  
  599. clean:
  600.     rm -f $(OFILES) demo
  601.     
  602. Char.o : Char.m Char.h 
  603.  
  604. Float.o : Float.m Float.h 
  605.  
  606. Node.o : Node.m Node.h 
  607.  
  608. Queue.o : Queue.m Queue.h Node.h 
  609.  
  610. Stack.o : Stack.m Stack.h Node.h 
  611.  
  612. main.o : main.m Queue.h Node.h Stack.h Float.h
  613. @EOF
  614. set `wc -lwc <objc-sample/Makefile`
  615. if test $1$2$3 != 35115689
  616. then
  617.     echo ERROR: wc results of objc-sample/Makefile are $* should be 35 115 689
  618. fi
  619.  
  620. chmod 644 objc-sample/Makefile
  621.  
  622. if test -f objc-sample/Float.m
  623. then
  624.     echo Ok to overwrite existing file objc-sample/Float.m\?
  625.     read answer
  626.     case "$answer" in
  627.     [yY]*)    echo Proceeding;;
  628.     *)    echo Aborting; exit 1;;
  629.     esac
  630.     rm -f objc-sample/Float.m
  631.     if test -f objc-sample/Float.m
  632.     then
  633.         echo Error: could not remove objc-sample/Float.m, aborting
  634.         exit 1
  635.     fi
  636. fi
  637. echo x - objc-sample/Float.m
  638. cat >objc-sample/Float.m <<'@EOF'
  639. #import <stdio.h>
  640. #import "Float.h"
  641.  
  642. @implementation Float
  643. {
  644.   float value;
  645. }
  646.  
  647. - init: (float) x
  648. {
  649.   [super init];        // In case the parent class is doing
  650.               // something special in its init...
  651.   value = x;
  652.   return self;
  653. }
  654.  
  655. - report
  656. {
  657.   printf("%4.1f", value);
  658.   return self;
  659. }
  660.  
  661. @end
  662. @EOF
  663. set `wc -lwc <objc-sample/Float.m`
  664. if test $1$2$3 != 2346285
  665. then
  666.     echo ERROR: wc results of objc-sample/Float.m are $* should be 23 46 285
  667. fi
  668.  
  669. chmod 644 objc-sample/Float.m
  670.  
  671. if test -f objc-sample/main.m
  672. then
  673.     echo Ok to overwrite existing file objc-sample/main.m\?
  674.     read answer
  675.     case "$answer" in
  676.     [yY]*)    echo Proceeding;;
  677.     *)    echo Aborting; exit 1;;
  678.     esac
  679.     rm -f objc-sample/main.m
  680.     if test -f objc-sample/main.m
  681.     then
  682.         echo Error: could not remove objc-sample/main.m, aborting
  683.         exit 1
  684.     fi
  685. fi
  686. echo x - objc-sample/main.m
  687. cat >objc-sample/main.m <<'@EOF'
  688. // main.m - comp.lang.objective-c simple sample Objective-C program
  689.  
  690. // This is a comment.  Everything to the right of a double slash
  691. // is ignored.
  692.  
  693. /*
  694.  * This is too.  Objective-C is a superset of ANSI C,
  695.  * so you don't lose any of your favorite features.
  696.  */
  697.  
  698. // Classes are the one real extension which Objective C adds to
  699. // ANSI C.  A class is a description of a collection of data, like
  700. // a C structure, and the methods by which that data may be accessed
  701. // or manipulated.  Instances of a class are called objects, and
  702. // methods are invoked by sending messages to either the class itself,
  703. // to produce objects, or to those objects.  The recipient of a message
  704. // is called a "receiver".  The form of a message is:
  705. //
  706. //    [receiver method andMaybeSomeArguments]
  707. //
  708. // the receiver and method components are mandatory, as are 
  709.  
  710. // the square brackets surrounding the message.  Additional
  711. // arguments may or may not be present, depending upon the
  712. // method definition.  Messages may appear anywhere a statement
  713. // is allowed in C.
  714.  
  715. // The first thing we do is bring in some include files, as in
  716. // C.  However, we'll use the "import" statement which guarantees
  717. // that the file isn't included more than once.
  718.  
  719. #import <stdio.h>
  720. #import <objc/Object.h>
  721. #import "Queue.h"
  722. #import "Stack.h"
  723.  
  724. // That brought in class definitions for Objects, Queues, and
  725. // Stacks.  The Object class is the basis for all other classes,
  726. // which is why it gets brought in first.  It provides basic functional
  727. // behavior which is inherited by all derived classes.  All user
  728. // created classes should have Object somewhere in their ancestry.
  729.  
  730. // Queue and Stack are classes of our own construction,
  731. // and provide FIFO and LIFO storage capabilities, respectively.
  732. // I'm not going to go into implementation details here.  It's
  733. // irrelevant how they work, all that is important is that they
  734. // both respond to 'put:' and 'get'.  If you want to inspect them,
  735. // look into the Queue.m, Stack.m, Queue.h and Stack.h files.
  736.  
  737. // A simple Class definition follows.  It inherits
  738. // directly from the base class "Object".  This gives
  739. // it lots of nice properties, not the least of which
  740. // is the ability to be referenced by any pointer of the
  741. // generic object type "id".  All objects can be pointed
  742. // to by any id variable, and the default return type from
  743. // methods is id.  This allows messages to be embedded in
  744. // other messages, either as receivers or arguments.
  745.  
  746. // An Int object allocates space for a single integer.
  747. // The "report" message causes it to report its value.
  748. // Everything between the @implementation and the @end
  749. // is part of the class definition.
  750.  
  751. // Note - It is *highly* unusual to have a class implementation
  752. // in your main program.  Since the object is fully defined before
  753. // it gets used, no interface description is required.  There is
  754. // nothing illegal about doing things this way, but it is so
  755. // unusual that the compiler will produce a warning for this class.
  756. // We have included the Int class implementation here solely for
  757. // expository purposes.
  758.  
  759. @implementation Int: Object    // Int is derived from Object
  760. {
  761.     int value;        // This is the data portion.  Like a struct.
  762. }
  763.  
  764. // The following are the method definitions.  A "+" prefix means
  765. // it is a factory method, i.e., how to manufacture instances of
  766. // the class.  The body of the method is between braces, like a C
  767. // function.
  768.  
  769. // This class doesn't define any factory methods.  It relies on the
  770. // +alloc method defined in class Object.  For examples of factory
  771. // methods, look at the +new method defined in the Stack or
  772. // Queue implementations.
  773.  
  774. // Self is a special variable, which refers to the object currently
  775. // being manipulated.  Super refers to the parent class of self.
  776. // The following method asks the parent class (Object) to hand us a
  777. // new instance, which becomes self.  Then we update the instance
  778. // variables and return a pointer to the new object.
  779.  
  780. // It is standard for methods that do not need to return any
  781. // special value to instead return self.  This allows for a 
  782. // nested syntax of method calls.
  783.  
  784. // The "-" in front of init means that it's an instance method,
  785. // i.e., something a particular object should respond to.
  786.  
  787. - init: (int) i        // This method will initialize a new Int 
  788. {
  789.   [super init];        // In case the parent class is doing
  790.               // something special in its init...
  791.   value = i;
  792.   return self;
  793. }
  794.  
  795. - report
  796. {
  797.   printf("%4d", value);
  798.   return self;
  799. }
  800.  
  801. @end
  802.  
  803. // We have implemented Float and Char classes more traditionally, using
  804. // separate files for the interface (.h) and implementation (.m).
  805. // The Float and Char objects are like the Int object, but with the
  806. // obvious difference that they work with floats and characters.
  807. // We include the interface definitions at this point.
  808.  
  809. #import "Float.h"
  810. #import "Char.h"
  811.  
  812. // If you inspect those files, note polymorphism -- methods have same
  813. // names as in the Int class.
  814.  
  815. int main(void)
  816. {
  817.     // First we create instances of "Stack" and "Queue" data structures
  818.  
  819.     id queue = [Queue new];    // +new is an older convention for
  820.     id stack = [Stack new];    // allocation & initialization.
  821.                     // [[x alloc] init] is the preferred
  822.                 // way to do this now.
  823.     int i;
  824.     int reply;
  825.     
  826.     fprintf(stderr, "Include the Char class in the demo? (y/n): ");
  827.     reply = getchar();    // no error checking...
  828.  
  829.     for (i = 5; i > -6; --i)
  830.     {
  831.     // Depending on which version of the demo we're running,
  832.     // we alternate putting Int's and Floats onto the queue and
  833.     // stack, or Int's, Float's, and Char's.
  834.  
  835.     if (reply == 'y')
  836.     {
  837.         // If "i" is odd we put an Int on the queue and a Char on
  838.         // the stack.  If "i" is even we put an Char on the queue
  839.         // and a Float on the stack.
  840.  
  841.         // Since there is more than one method "init", and
  842.         // Objective-C uses run-time binding, the compiler doesn't
  843.         // know what the type of the object returned by alloc.
  844.         // We disambiguate with an explicit C-style cast to make
  845.         // sure the appropriate "init" is invoked. 
  846.  
  847.             [queue put: (i & 1) ?
  848.                 [(Int*)[Int alloc] init: i] :
  849.           [(Char*)[Char alloc] init: 'm'+i]];
  850.             [stack put: (i & 1) ?
  851.                 [(Char*)[Char alloc] init: 'm'+i] :
  852.           [(Float*)[Float alloc] init: i]];
  853.     }
  854.     else    // Note - garbage input will invoke the else clause.
  855.     {
  856.         // If "i" is odd we put an Int on the queue and a Float on
  857.         // the stack.  If "i" is even we put a Float on the queue
  858.         // and an Int on the stack.
  859.  
  860.             [queue put: (i & 1) ?
  861.                 [(Int*)[Int alloc] init: i] :
  862.           [(Float*)[Float alloc] init: i]];
  863.             [stack put: (i & 1) ?
  864.                 [(Float*)[Float alloc] init: i] :
  865.           [(Int*)[Int alloc] init: i]];
  866.     }
  867.     }
  868.  
  869.     while ([queue size] && [stack size])
  870.     {
  871.     // The following illustrates run-time binding.  Will report be
  872.     // invoked for a Float object or an Int object?  Did the user
  873.     // elect for Char objects at run time?  We don't know ahead
  874.     // of time, but with run-time binding and polymorphism
  875.     // it works properly.  The burden is on the class
  876.     // implementer rather than the class user.  
  877.  
  878.     // Note that the following lines remain unchanged, whether
  879.     // we are using the Char class or not.  The queue and stack
  880.     // hand us the next object, it reports itself regardless
  881.     // of its type, and then it frees itself.
  882.  
  883.     printf("queue:");    [[[queue get] report] free];
  884.     printf(", stack:");    [[[stack get] report] free];
  885.     putchar('\n');
  886.     }
  887.     return 0;
  888. }
  889. @EOF
  890. set `wc -lwc <objc-sample/main.m`
  891. if test $1$2$3 != 20112937504
  892. then
  893.     echo ERROR: wc results of objc-sample/main.m are $* should be 201 1293 7504
  894. fi
  895.  
  896. chmod 644 objc-sample/main.m
  897.  
  898. if test -f objc-sample/Float.h
  899. then
  900.     echo Ok to overwrite existing file objc-sample/Float.h\?
  901.     read answer
  902.     case "$answer" in
  903.     [yY]*)    echo Proceeding;;
  904.     *)    echo Aborting; exit 1;;
  905.     esac
  906.     rm -f objc-sample/Float.h
  907.     if test -f objc-sample/Float.h
  908.     then
  909.         echo Error: could not remove objc-sample/Float.h, aborting
  910.         exit 1
  911.     fi
  912. fi
  913. echo x - objc-sample/Float.h
  914. cat >objc-sample/Float.h <<'@EOF'
  915. #import <objc/Object.h>
  916.  
  917. @interface Float: Object
  918. {
  919.   float value;
  920. }
  921.  
  922. - init: (float) x;
  923. - report;
  924.  
  925. @end
  926. @EOF
  927. set `wc -lwc <objc-sample/Float.h`
  928. if test $1$2$3 != 1116105
  929. then
  930.     echo ERROR: wc results of objc-sample/Float.h are $* should be 11 16 105
  931. fi
  932.  
  933. chmod 644 objc-sample/Float.h
  934.  
  935. if test -f objc-sample/COPYRIGHT
  936. then
  937.     echo Ok to overwrite existing file objc-sample/COPYRIGHT\?
  938.     read answer
  939.     case "$answer" in
  940.     [yY]*)    echo Proceeding;;
  941.     *)    echo Aborting; exit 1;;
  942.     esac
  943.     rm -f objc-sample/COPYRIGHT
  944.     if test -f objc-sample/COPYRIGHT
  945.     then
  946.         echo Error: could not remove objc-sample/COPYRIGHT, aborting
  947.         exit 1
  948.     fi
  949. fi
  950. echo x - objc-sample/COPYRIGHT
  951. cat >objc-sample/COPYRIGHT <<'@EOF'
  952. This copyright notice applies to all source files distributed in the
  953. comp.lang.objective-c FAQ: `A simple sample Objective-C program'.
  954.  
  955. Copyright (C) 1993 Bill Shirley and Paul Burchard
  956.  
  957. The `simple sample Objective-C program' is free software; you can
  958. redistribute it and/or modify it under the terms of the GNU General Public
  959. License as published by the Free Software Foundation; either version 2, or
  960. (at your option) any later version.
  961.  
  962. The `simple sample Objective-C program' is distributed in the hope that it
  963. will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  964. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
  965. Public License for more details.
  966.  
  967. You should have received a copy of the GNU General Public License
  968. along with GNU Emacs; see the file COPYING.  If not, write to
  969. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  970. @EOF
  971. set `wc -lwc <objc-sample/COPYRIGHT`
  972. if test $1$2$3 != 18143900
  973. then
  974.     echo ERROR: wc results of objc-sample/COPYRIGHT are $* should be 18 143 900
  975. fi
  976.  
  977. chmod 644 objc-sample/COPYRIGHT
  978.  
  979. chmod 755 objc-sample
  980.  
  981. exit 0
  982. -- 
  983. --Tiggr
  984.